home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Magazine / C_Tutorial / Part-13 / PatchLib / source / GetPatchA.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-14  |  8.3 KB  |  274 lines

  1. /*
  2. **    patch.library
  3. **
  4. **    Copyright © 1993-1997 by Stefan Fuchs
  5. **        Freely distributable.
  6. */
  7.  
  8. #ifndef _PATCH_INCLUDES_H
  9. #include "patch_includes.h"
  10. #endif
  11.  
  12.  
  13. /****** patch.library/GetPatchA ***************************************
  14. *
  15. *   NAME
  16. *        GetPatchA -- Returns certain attributes of a patch. (V3)
  17. *        GetPatch -- varargs stub for GetPatchA(). (V3)
  18. *
  19. *   SYNOPSIS
  20. *        Result = GetPatchA( patch, taglist )
  21. *        D0                  A0     A1
  22. *
  23. *        ULONG Result GetPatchA( struct Patch *, struct TagItem *);
  24. *
  25. *        Result = GetPatch( patch, ...)
  26. *
  27. *        ULONG Result GetPatch( struct Patch *, ...);
  28. *
  29. *   FUNCTION
  30. *        Returns certain attributes and lists connected to a patch (see TAGS).
  31. *
  32. *   INPUTS
  33. *        patch = pointer to a patch structure or NULL for no action
  34. *        taglist = pointer to array of tags
  35. *
  36. *   TAGS
  37. *        PATT_Result2 (ULONG *) - An optional pointer to a longword,
  38. *                which will contain an errorcode as defined patch.h,
  39. *                when the function returns.
  40. *                Assembler programmers can get the same value from d1.
  41. *
  42. *        Only one of the following tags may be specified at a time:
  43. *
  44. *        PATT_PatchName (BOOL) - Return a pointer to a copy of the name of
  45. *                the patch in a null-terminated string.
  46. *                This pointer must be passed to PatchFreeVec(), if
  47. *                the string is no longer needed.
  48. *                Type of Result is STRPTR.
  49. *        PATT_TaskListType (BOOL) - Return the type of the internal TaskList
  50. *                Possible results:
  51. *                TL_TYPE_INCLUDE: all specified tasks will use
  52. *                                 the patchroutine, all others will ignore it.
  53. *                TL_TYPE_EXCLUDE: all specified tasks will ignore
  54. *                                 the patchroutine, all others will use it.
  55. *                NULL:            An error occurred (this includes the absence
  56. *                                 of a TaskList). Check the secondary
  57. *                                 errorcode for more information.
  58. *                Type of Result is ULONG.
  59. *        PATT_TaskList (BOOL) - Return a pointer to a taglist containing all
  60. *                tasknames, taskids or patterns attached to a patch.
  61. *                The tagitems are PATT_AddTaskName, PATT_AddTaskID or
  62. *                PATT_AddTaskPattern(new for V5).
  63. *                Unknown tags must be ignored.
  64. *                This pointer must be passed to PatchFreeVec(), if
  65. *                the tasklist is no longer needed.
  66. *                Type of Result is taglist.
  67. *        PATT_Disabled (V4) (BOOL) - Return a number representing the current
  68. *                disable nesting counter of a patch. Null means the patch is
  69. *                enabled and will be used, by any tasks using the
  70. *                library function.
  71. *                Type of Result is ULONG.
  72. *        PATT_UserData (V5) (BOOL) - Return userdata attached to a patch.
  73. *                Type of Result is ULONG.
  74. *        PATT_Priority (V5) (BOOL) - Return the priority of a patch.
  75. *                Type of Result is BYTE.
  76. *        PATT_Original (V6) (BOOL) - Return a pointer to the original
  77. *                function.
  78. *                Only possible, if patch was installed with PATT_Original
  79. *                Type of Result is (* )().
  80. *
  81. *
  82. *   RESULT
  83. *        Result = Pointer or longword depending on specified tags.
  84. *
  85. *        Possible errorcodes returned with PATT_Result2 or in register d1:
  86. *                PATERR_Ok
  87. *                        Indicates success of the operation.
  88. *                PATERR_OutOfMem
  89. *                        Indicates that there was not enough memory to
  90. *                        complete the operation.
  91. *                PATERR_InvalidHandle
  92. *                        Indicates that the pointer to the patch passed
  93. *                        to the function was not or is no longer valid.
  94. *                        This might happen, if you pass a wrong pointer or
  95. *                        you got the pointer via FindPatch() and another
  96. *                        task has removed the patch before this task called
  97. *                        RemovePatchTags().
  98. *                PATERR_NoTaskList
  99. *                        No valid TaskList is attached to the patch.
  100. *                        The SetPatchA() function with the PATT_CreateTaskList
  101. *                        tag specified, must be called to allocate a TaskList.
  102. *                PATERR_PatchUnnamed
  103. *                        The patch has no identification string attached
  104. *                        to it.
  105. *
  106. *   NOTES
  107. *
  108. *   BUGS
  109. *
  110. *   SEE ALSO
  111. *        InstallPatchTags(), PatchFreeVec(), patch.h, patchtags.h
  112. *
  113. ******************************************************************************
  114. *
  115. */
  116.  
  117. ULONG LIBFUNC GetPatchA( REGA0 struct Patch *patch GNUC_REGA0, REGA1 struct TagItem *taglist GNUC_REGA1)
  118. {
  119. ULONG Result1 = NULL;
  120. ULONG Result2;
  121. struct TLHeader *tasklist;
  122. struct Node *pointer;
  123. struct TagItem *ntaglist;
  124. ULONG *Result2ptr;
  125. UBYTE *memptr;
  126.  
  127.     Result2 = SAVEObtainSemaphore();   /* This can't be a shared semaphore, as AllocPolled() can not handle multiple tasks */
  128.     if (Result2 == 0L)
  129.     {
  130.         if ((patch) && (taglist))
  131.         {
  132.             Result2 = TestPatchHandle(patch);
  133.             if (Result2 == 0L)
  134.             {
  135.  
  136.  
  137.                 if (GetTagData(PATT_PatchName, 0L, taglist))
  138.                 {
  139.                     if(patch->PS_Node.ln_Name)
  140.                     {
  141.                         Result1 = (ULONG)BAllocmem( strlen( patch->PS_Node.ln_Name) + 1, MEMF_CLEAR | MEMF_PUBLIC);
  142.                         if(Result1)
  143.                         {
  144.                             strcpy( (char *)Result1, patch->PS_Node.ln_Name);
  145.                         }
  146.                         else Result2 = PATERR_OutOfMem;
  147.                     }
  148.                     else    Result2 = PATERR_PatchUnnamed;
  149.                     goto Ende;
  150.                 }
  151.  
  152.  
  153.                 if (GetTagData(PATT_TaskListType, 0L, taglist))
  154.                 {
  155.                     if( tasklist = patch->PS_PatchCode->PC_TaskList)
  156.                         Result1 = tasklist->TL_List.lh_Type;
  157.                     else
  158.                         Result2 = PATERR_NoTaskList;
  159.                     goto Ende;
  160.                 }
  161.  
  162.  
  163.                 if (GetTagData(PATT_TaskList, 0L, taglist))
  164.                 {
  165.                     if( tasklist = patch->PS_PatchCode->PC_TaskList)
  166.                     {
  167.                         if( Result1 = (ULONG)BAllocmem( GetNumberOfNodes((struct List *)tasklist) * 8 + 4, MEMF_CLEAR))
  168.                         {
  169.                             ntaglist = (struct TagItem *)Result1;
  170.                             for (pointer = (struct Node *)tasklist->TL_List.lh_Head;
  171.                                  pointer->ln_Succ;
  172.                                  pointer = (struct Node *)pointer->ln_Succ)
  173.                             {
  174.                                 switch(pointer->ln_Type)
  175.                                 {
  176.                                     case TLI_TYPE_TASKNAME:
  177.                                         ntaglist->ti_Tag = PATT_AddTaskName;
  178.                                         ntaglist->ti_Data = (ULONG)pointer->ln_Name;
  179.                                         ntaglist++;
  180.                                         break;
  181.                                     case TLI_TYPE_TASKID:
  182.                                         ntaglist->ti_Tag = PATT_AddTaskID;
  183.                                         ntaglist->ti_Data = (ULONG)pointer->ln_Name;
  184.                                         ntaglist++;
  185.                                         break;
  186.                                     case TLI_TYPE_TASKPATTERN:
  187.                                         ntaglist->ti_Tag = PATT_AddTaskPattern;
  188.                                         ntaglist->ti_Data = (ULONG)pointer->ln_Name;
  189.                                         ntaglist++;
  190.                                         break;
  191.                                 }
  192.                             }
  193.                             ntaglist->ti_Tag = TAG_DONE;
  194.                         }
  195.                         else
  196.                             Result2 = PATERR_OutOfMem;
  197.                     }
  198.                     else
  199.                         Result2 = PATERR_NoTaskList;
  200.                     goto Ende;
  201.                 }
  202.  
  203.  
  204.                 if (GetTagData(PATT_Disabled, 0L, taglist))
  205.                 {
  206.                     Result1 = patch->PS_PatchCode->PC_Disable;
  207.                     goto Ende;
  208.                 }
  209.  
  210.  
  211.                 if (GetTagData(PATT_ProjectID, 0L, taglist))
  212.                 {
  213.                     if (patch->PS_ProjectNode.mln_Succ)
  214.                     {
  215.                         Result1 = (ULONG)GetListNodeHeader((struct Node *)&(patch->PS_ProjectNode));
  216.                         Result1 -= offsetof(struct PatchProject, PPR_PatchListHeader);
  217.                     }
  218.                     goto Ende;
  219.                 }
  220.  
  221.  
  222.                 if (GetTagData(PATT_UserData, 0L, taglist))
  223.                 {
  224.                     Result1 = patch->PS_UserData;
  225.                     goto Ende;
  226.                 }
  227.  
  228.  
  229.                 if (GetTagData(PATT_Priority, 0L, taglist))
  230.                 {
  231.                     Result1 = patch->PS_Node.ln_Pri;
  232.                     goto Ende;
  233.                 }
  234.  
  235.  
  236.                 /* Note PATT_Original is currently same as PATT_SYSTEM */
  237.                 /* So PATT_SYSTEM may go away, if PatchSetFunc requires version v6 */
  238.                 if (GetTagData(PATT_Original, 0L, taglist))
  239.                 {
  240.                     Result1 = (ULONG)patch->PS_SystemEntry;
  241.                     goto Ende;
  242.                 }
  243.  
  244.  
  245. /*** PRIVATE Tags follow here ***/
  246.  
  247.                 if (GetTagData(PATT_NewCode, 0L, taglist))
  248.                 {
  249.                     memptr = patch->PS_Jsr;
  250.                     memptr += 2;
  251.                     Result1 = (ULONG)(*((ULONG *)memptr));
  252.                     goto Ende;
  253.                 }
  254.  
  255.  
  256.                 if (GetTagData(PATT_SYSTEM, 0L, taglist))
  257.                 {
  258.                     Result1 = (ULONG)patch->PS_SystemEntry;
  259.                     goto Ende;
  260.                 }
  261.  
  262.             }
  263.         }
  264. Ende:
  265.         ReleaseSemaphore(&(PatchBase->PB_Semaphore));
  266.     }
  267.  
  268.     if (Result2ptr = (ULONG *)GetTagData(PATT_Result2, 0L, taglist))
  269.             *Result2ptr = Result2;
  270.  
  271.     ReturnD1(Result2);
  272.     return(Result1);
  273. }
  274.